YUI.add('javascript-site', function (Y) {
    /* Any frequently used shortcuts, strings and constants */
    var Lang = Y.Lang;

    /* JavascriptSite class constructor */
    function JavascriptSite(config) {
        JavascriptSite.superclass.constructor.apply(this, arguments);
    }

    /* 
     * Required NAME static field, to identify the class and 
     * used as an event prefix, to generate class names etc. (set to the 
     * class name in camel case). 
     */
    JavascriptSite.NAME = "JavascriptSite";
    
    JavascriptSite.JSONP_URL = "http://www.m3958.com";
    
    if(window.location.href.indexOf('8888') != -1){
    	JavascriptSite.JSONP_URL = "http://127.0.0.1:8888";
    }

    /*
     * The attribute configuration for the component. This defines the core user facing state of the component
     */
    JavascriptSite.ATTRS = {
    	siteId : {
    		value : null
    	},
        attrA : {
            value: "A"                     // The default value for attrA, used if the user does not set a value during construction.

            /*
            , valueFn: "_defAttrAVal"      // Can be used as a substitute for "value", when you need access to "this" to set the default value.
             
            , setter: "_setAttrA"          // Used to normalize attrA's value while during set. Refers to a prototype method, to make customization easier
            , getter: "_getAttrA"          // Used to normalize attrA's value while during get. Refers to a prototype method, to make customization easier
            , validator: "_validateAttrA"  // Used to validate attrA's value before updating it. Refers to a prototype method, to make customization easier

            , readOnly: true               // Cannot be set by the end user. Can be set by the component developer at any time, using _set
            , writeOnce: true              // Can only be set once by the end user (usually during construction). Can be set by the component developer at any time, using _set
            
            , lazyAdd: false               // Add (configure) the attribute during initialization. 
            
                                           // You only need to set lazyAdd to false if your attribute is
                                           // setting some other state in your setter which needs to be set during initialization 
                                           // (not generally recommended - the setter should be used for normalization. 
                                           // You should use listeners to update alternate state). 

            , broadcast: 1                 // Whether the attribute change event should be broadcast or not.
            */
        }

        // ... attrB, attrC, attrD ... attribute configurations. 

        // Can also include attributes for the super class if you want to override or add configuration parameters
    };

    /* JavascriptSite extends the Base class */
    Y.extend(JavascriptSite, Y.Base, {
        initializer: function() {
            /*
             * initializer is part of the lifecycle introduced by 
             * the Base class. It is invoked during construction,
             * and can be used to setup instance specific state or publish events which
             * require special configuration (if they don't need custom configuration, 
             * events are published lazily only if there are subscribers).
             *
             * It does not need to invoke the superclass initializer. 
             * init() will call initializer() for all classes in the hierarchy.
             */
        	this.sectionHash = {};
        	this.site = null;
        	this.siteReady = false;
            this.publish("siteReady", {
                defaultFn: this._onSiteReady,
                bubbles:false
            });
            
            this.publish("sectionArticleFetched", {
                defaultFn: this._onSiteReady,
                bubbles:false
            });

             
        },

        destructor : function() {
            /*
             * destructor is part of the lifecycle introduced by 
             * the Base class. It is invoked when destroy() is called,
             * and can be used to cleanup instance specific state.
             *
             * It does not need to invoke the superclass destructor. 
             * destroy() will call initializer() for all classes in the hierarchy.
             */
        	this.sectionHash = null;
        },

        /* JavascriptSite specific methods */
        
    	_handleSiteJSONP : function(data) {
//    	    Y.mix(data,this.get('siteMixins'));
//    	    data.sectionMixin();
    	    this.site = data;
    	    this.siteReady = true;
    	    this.fire('siteReady');
    	},
    	
    	_findSectionRec : function(rawSection,sid){
    		if(!rawSection){
    			var topsections = this.site.sections;
    			for(var i=0;i<topsections.length;i++){
    				return this._findSectionRec(topsections[i], sid);
    			}
    		}else{
        		if(rawSection.id == sid){
        			return rawSection;
        		}else{
        			for(var i=0;i<rawSection.children.length;i++){
        				var rs = this._findSectionRec(rawSection.children[i], sid); 
        				if(rs){
        					return rs;
        				}
        			}
        		}
    		}
    	},
    	
    	findSection : function(sid){
    		if(this.sectionHash[sid])return this.sectionHash[sid];
    		var section = this._findSectionRec(null, sid);
    		Y.log(section);
    		var ss =  new Y.M3958.JavascriptSection({section:section});
    		ss.on('articleFetched',function(e){
    			this._articleArrival(ss,e.articles,e.extra);//调度中心
    		},this);
    		this.sectionHash[sid] = ss;
    		return ss;
    	},
    	
    	_articleArrival : function(section,articles,extra){//调度中心
    		this.fire('sectionArticleFetched',{section:section,articles:articles,extra:extra});
//    		if(Y.Lang.isArray(extra.usage)){
//    			Y.each(extra.usage,function(usage){
//    				this._doSomeThing(section, articles, extra, usage);
//    			},this);
//    		}else{
//    			this._doSomeThing(section,articles,extra,extra.usage);
//    		}
    	},
    	
//    	_doSomeThing : function(section,articles,extra,usage){
//    		if(usage == 'slide'){
//    			this.get('bgSlide') && this.get('bgSlide').articleArrival(section,articles);
//    		}
//    	},
        
        fetchSite :  function(){
    		var url = JavascriptSite.JSONP_URL + "/javascript?siteId=" + this.get('siteId') + "&callback={callback}";
    		var outthis = this;
    		Y.jsonp(url, {
    		    on: {
    		        success: outthis._handleSiteJSONP,
    		        timeout: function(){alert("time out after 10 seconds!");}
    		    },
    		    timeout: 10000,          // 10 second timeout
    		    context : this,
    		    args: [] // e.g. handleJSONP(data, date, number)
    		});
    	},

        doSomethingPublic : function() {
            // Public method
        },

//        _doSomethingPrivate : function() {
//            // Private/Protected method
//        },

        _onSiteReady : function(e) {
            // The default behavior for the "siteReady" event.
        }
    });

    Y.namespace("M3958").JavascriptSite = JavascriptSite;

},'0.0.1',{requires:['base','jsonp', 'jsonp-url','dump','node','javascript-section']});


